package com.logreview.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

public class CoreSocketClient {
    private Socket socket;
    private SocketAddress address;
    private String encode = "gbk";
    private Logger logger = LoggerFactory.getLogger(CoreSocketClient.class);

    public CoreSocketClient(String ipAddress,int port) {
        try {
            socket = new Socket();
            address = new InetSocketAddress(ipAddress, port);
            socket.connect(address, 1000);
        } catch (IOException e) {
            logger.error("connect to hds gateway failed",e);
        }

    }
    /**
     * 加密&发送报文
     * @throws Exception
     */
    public String sendData(byte[] key,String data) throws Exception{
        byte[] transBytes = MNTR.encrypt(data.getBytes(encode), key);
        //发送
        //一个数据包最长= 1+4+256
        byte[] bag;
        int bagNum = 0;//数据包的个数
        int bagIndex= 0;//已封装的传输包的index
        if(transBytes.length%256==0){
            bagNum = transBytes.length/256;
        }else{
            bagNum = transBytes.length/256+1;
        }
        //System.out.println("总字节数:"+transBytes.length);
        for (int ii = 0; ii < bagNum; ii++) {
            //剩余字节的数量
            int n = 0;
            if(bagNum == 1){
                n = transBytes.length;
                bag = new byte[n+5];
            }else{
                //剩余字节量 = 传输总数量 - 已发送的字节数量 + 当前包字节的数量
                n = transBytes.length - 256*(ii+1) + 256;
                if(n >= 256){
                    bag = new byte[256+5];
                }else{
                    bag = new byte[n+5];
                }
            }
            byte[] ns = ByteUtil.int2bytes(n);

            bag[0]=0x02;
            bag[1]=ns[0];
            bag[2]=ns[1];
            bag[3]=ns[2];
            bag[4]=ns[3];

            if(bagNum == 1){ //只有一个包的情况
                for (int jj = 5; jj < transBytes.length+5; jj++) {
                    System.out.println("jj="+jj+",bagIndex="+bagIndex);
                    bag[jj]=transBytes[bagIndex];
                    bagIndex++;
                }
            }else{ //有多个包
                if(ii < bagNum-1){//非最后一个包
                    for (int jj = 5; jj < 256+5; jj++) {
                        bag[jj]=transBytes[bagIndex];
                        bagIndex++;
                    }
                }else{//最后一个包
                    for (int jj = 5; jj < n+5; jj++) {
                        bag[jj]=transBytes[bagIndex];
                        bagIndex++;
                    }
                }
            }

            //发送包
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.write(bag);
            dos.flush();
            //System.out.println("send! bag.length="+bag.length+",剩余字节="+n);
            //包初始化
            bag = new byte[261];
        }
        socket.shutdownOutput();

        DataInputStream dis = new DataInputStream(socket.getInputStream());
        byte[] b = new byte[1];
        byte[] response = new byte[5+64];
        int rindex=0;
        while(dis.read(b) != -1){
            response[rindex]=b[0];
            rindex++;
        }


        String result = new String( MNTR.decrypt(response, key),encode);
        logger.info("服务器返回（解密）：{}",result);

        socket.close();

        return result;
    }

    /**
     * 申请密钥
     * @throws IOException
     */
    public String apply4Key() throws IOException {
        byte [] data = new byte[13];
        data[0]=0x04;
        data[1]=0x00;
        data[2]=0x00;
        data[3]=0x00;
        data[4]=0x00;
        data[5]=0x03;
        data[6]=0x05;
        data[7]=0x11;
        data[8]=0x56;
        data[9]=0x1f;
        data[10]=0x3A;
        data[11]=(byte) 0xF4;
        data[12]=(byte) 0xD5;
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.write(data);
        dos.flush();
        socket.shutdownOutput();

        DataInputStream dis = new DataInputStream(socket.getInputStream());

        byte[] b = new byte[1];
        byte[] byteEncryptKey = new byte[8]; //加密之后的通信密钥
        byte[] response = new byte[13];
        int rindex=0;
        while(dis.read(b) != -1){
            response[rindex]=b[0];
            rindex++;
        }

        byteEncryptKey[0]=response[5];
        byteEncryptKey[1]=response[6];
        byteEncryptKey[2]=response[7];
        byteEncryptKey[3]=response[8];
        byteEncryptKey[4]=response[9];
        byteEncryptKey[5]=response[10];
        byteEncryptKey[6]=response[11];
        byteEncryptKey[7]=response[12];

        dis.close();
//		socket.shutdownInput();



        //解密通信密钥
        byte [] decryptKey = new byte[8];
        decryptKey[0]=0x03;
        decryptKey[1]=0x05;
        decryptKey[2]=0x11;
        decryptKey[3]=0x56;
        decryptKey[4]=0x1f;
        decryptKey[5]=0x3A;
        decryptKey[6]=(byte) 0xF4;
        decryptKey[7]=(byte) 0xD5;

        byte [] key = DES.decrypt(byteEncryptKey, decryptKey);

        return new String(key);
    }

    public void closeSocket() throws IOException{
        socket.close();
    }

    public static void main(String[] args) throws Exception {
        CoreSocketClient test = new CoreSocketClient("127.0.0.1",18900);
        String key = test.apply4Key();
        System.out.println("key="+key);
        test.closeSocket();

        CoreSocketClient test1 = new CoreSocketClient("127.0.0.1",18900);
        String data = "00000012345678123456781234567812345678123456781234567";
        test1.sendData(key.getBytes("gbk"),data);
        test1.closeSocket();
    }
}
